package APP2.bookshop.main;


import APP2.bookshop.book.*;
import APP2.bookshop.author.Author;
import APP2.bookshop.publisher.Publisher;
import APP2.bookshop.GUI.MainFrame;
import APP2.bookshop.controller.AuthorController;
import APP2.bookshop.controller.BookController;
import APP2.bookshop.controller.OrderController;
import APP2.bookshop.controller.PublisherController;
import APP2.bookshop.order.Order;
import APP2.bookshop.order.OrderInfo;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 *
 * @author Asus
 */
public class BookShop {

    // handmade utility
    private static final int npublishers = 3;
    private static final int nauthors = 6;
    private static final int nbooks = 10;
    private static final int norders = 6;
    private static final int maxauthorsforbook = 3;
    private static final int nstockcopies = 5;

    // shop elements
    private List<Book> books;
    private List<Author> authors;
    private List<Publisher> publishers;
    private List<OrderInfo> orders;
    private List<Stock> stocks;

    // controllers
    private BookController bookController;
    private AuthorController authorController;
    private PublisherController publisherController;
    private OrderController orderController;

    //gui
    private MainFrame GUI;

    public BookShop() {
        initTheShop();
        initControllers();

        populate();
        startGUI();
    }

    // initializing of the database
    private void initTheShop() {
        this.books = new ArrayList<Book>();
        this.authors = new ArrayList<Author>();
        this.publishers = new ArrayList<Publisher>();
        this.orders = new ArrayList<OrderInfo>();
        this.stocks = new ArrayList<Stock>();
    }

    private void initControllers() {
        this.bookController = new BookController(this);
        this.authorController = new AuthorController(this);
        this.publisherController = new PublisherController(this);
        this.orderController = new OrderController(this);
    }

    private void populate() {
        // add publishers
        for (int i = 0; i < npublishers; i++)
            this.publishers.add(new Publisher("PubName_" + Integer.toString(i), "pub@lish.er", "0001014", "00456"));

        // add authors
        for (int i = 0; i < nauthors; i++)
            this.authors.add(new Author("AuthorName_" + Integer.toString(i)));

        // add books
        for (int i = 0; i < nbooks; i++)
            this.books.add(new Book("Centanni_"+Integer.toString(i),
                    "http://www.url.com", new Date(), Book.BOOKTYPE.paper));

        // add for each book from 1 to 3 random authors
        // add for each book 1 random publisher
        // add for each book an instance of Stock with a random copy of that book
        Random rand = new Random();
        Stock s;
        int auths = 0;
        for (Book b : this.books) {
            // publisher
            Publisher p = this.publishers.get(rand.nextInt(npublishers));
            b.setPublisher(p);
            p.setBook(b);

            // add "auths" authors to b
            auths = 1 + rand.nextInt(maxauthorsforbook);
            for (int i = 0; i < auths; i++) {
                Author a = this.authors.get(rand.nextInt(nauthors));
                // keep guessing an author if the last one
                // guessed is already an author for the book b
                while (b.getAuthor().contains(a))
                    a = this.authors.get(rand.nextInt(nauthors));
                b.setAuthor(a);
                a.setBook(b);
            }

            // add stock
            s = new Stock(b, 1+rand.nextInt(nstockcopies));
            b.setStock(s);
            this.stocks.add(s);
        }

        // add orders
        int year = 2013;
        int orderMonth = 0, deliveryMonth = 0;
        int day;
        int randomPub = 0;
        int randBooks = 0;


        Date ordered, delivered;

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        
        for (int i = 0; i < norders; i++) {
            // create random date in the specified year
            // ordered date is lesser (in time) than delivered date
            orderMonth = 1 + (int)Math.round(Math.random() * (6 - 1));
            deliveryMonth = 7 + (int)Math.round(Math.random() * (12 - 7));
            day = 1 + (int)Math.round(Math.random() * (31 - 1));
            calendar.set(Calendar.MONTH, orderMonth);
            calendar.set(Calendar.DAY_OF_MONTH, day);
            ordered = calendar.getTime();
            calendar.set(Calendar.MONTH, deliveryMonth);
            delivered = calendar.getTime();

            // create order
            this.orders.add(new OrderInfo(i, ordered, delivered, Math.floor(1+(Math.random()*5))));

            // add random books from a single publisher in the order
            randomPub = rand.nextInt(npublishers);
            randBooks = rand.nextInt(this.getPublishers().get(randomPub).getBooks().size());

            Order order;
            int j = 0;
            for (Book b : this.publishers.get(randomPub).getBooks()) {
                order = new Order(1, b, this.orders.get(i));
                this.orders.get(i).addOrder(order);

                if (j++ >= randBooks)
                    break;
            }

            // debug
            System.out.println("SIZE ORDERS: " + Integer.toString(this.orders.size()));
        }


        
    }

    private void startGUI() {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                GUI = new MainFrame(BookShop.this);
                GUI.pack();
                GUI.setVisible(true);
            }
        });

    }

    public static void main(String[] args) {
        BookShop bookshop;
        bookshop = new BookShop();
    }


    // GET METHODS
    public List<Author> getAuthors() {
        return this.authors;
    }
    public List<Publisher> getPublishers() {
        return this.publishers;
    }
    public List<Book> getBooks() {
        return this.books;
    }
    public List<OrderInfo> getOrders() {
        return this.orders;
    }
    public BookController getBookController() {
        return this.bookController;
    }
    public AuthorController getAuthorController() {
        return this.authorController;
    }
    public PublisherController getPublisherController() {
        return this.publisherController;
    }
    public OrderController getOrderController() {
        return this.orderController;
    }
}
